﻿#include "WRAppContext.h"
#include "WRClass.h"
#include "WRAppServiceActivator.h"
#include "../WRConfig.h"

#include <QList>
#include <QHash>
#include <QFile>

//获取应用程序上下文唯一实例。
WRAppContext* WRAppContext::current(void)
{
    static WRAppContext value;
    return &value;
}

//初始化模块。
void WRAppContext::initModules(const QDomElement& config)
{
    QChar fileNameLiteral[] = {'f','i', 'l', 'e', 'N', 'a', 'm', 'e'};
    QString fileNameString = QString::fromRawData(fileNameLiteral, 8);
    QChar modulesLiteral[] = {'m','o', 'd', 'u', 'l', 'e', 's'};
    QString moduleString = QString::fromRawData(modulesLiteral, 6);
    QString modulesString = QString::fromRawData(modulesLiteral, 7);
    //从配置文件中加载所有模块
    QList<QLibrary*> modules;
    {
        QDomElement element = config.firstChildElement(modulesString);
        if (!element.isNull())
        {
            element = element.firstChildElement(moduleString);
            while(!element.isNull())
            {
                QLibrary* libray = new QLibrary(WRConfig::readValue(element, fileNameString));
                if (libray->load())
                {
                    modules.append(libray);
                }
                else
                {
                    delete libray;
                }
                element = element.nextSiblingElement(moduleString);
            }
        }
    }
    m_modules = modules;
}
//初始化服务。
void WRAppContext::initServices(const QDomElement& config)
{
    QChar servicesLiteral[] = {'s','e', 'r', 'v', 'i', 'c', 'e', 's'};
    QString serviceString = QString::fromRawData(servicesLiteral, 7);
    QString servicesString = QString::fromRawData(servicesLiteral, 8);
    //从配置文件中加载所有服务
    QList<WRAppService*> services;
    {
        QDomElement element = config.firstChildElement(servicesString);
        if (!element.isNull())
        {
            element = element.firstChildElement(serviceString);
            while(!element.isNull())
            {
                WRClass* _class = WRClass::select(element);
                if (_class)
                {
                    WRAppServiceActivator* activator = _class->cast<WRAppServiceActivator>(WRAppServiceActivatorType);
                    if (activator)
                    {
                        WRAppService* service = activator->create(element);
                        if(service)
                        {
                            services.append(service);
                        }
                    }
                }
                element = element.nextSiblingElement(serviceString);
            }
        }
    }
    m_services = services;
    //将服务进行散列存储
    typedef QList<WRAppService*> List;
    typedef QHash<QUuid, List*> Hash;
    Hash hash;
    for(WR32s i = 0; i < services.count(); ++i)
    {
        WRAppService* service = services[i];
        WRType* type = service->type();
        while(type)
        {
            Hash::ConstIterator iter = hash.find(type->uuid());
            if (iter != hash.end())
            {
                List* list = iter.value();
                list->append(service);
            }
            else
            {
                List* list = new List();
                list->append(service);
                hash.insert(type->uuid(), list);
            }
            type = type->base();
        }
    }
    if (hash.count())
    {
        WRArray<ServiceEntry> array(hash.count());
        WRu index = 0;
        for(QHash<QUuid, List*>::Iterator iter = hash.begin(); iter != hash.end(); iter++, ++index)
        {
            List* list = iter.value();
            array[index] = ServiceEntry(iter.key(), WRArray<WRAppService*>(*list));
            delete list;
        }
        m_serviceHash = array;
    }
}

//初始化上下文实例。
WRAppContext::WRAppContext(void)
{

}
//清理当前对象所占用的相关资源。
WRAppContext::~WRAppContext(void)
{
    for(WRu i = 0, l = m_services.count(); i < l; ++i)
    {
        WRAppService* entry = m_services[i];
        delete entry;
    }
    for(WRu i = 0, l = m_modules.count(); i < l; ++i)
    {
        QLibrary* entry = m_modules[i];
        entry->unload();
        delete entry;
    }
}

//执行相应的初始化处理。
void WRAppContext::initialize(const QDomElement& config)
{
    if (!config.isNull())
    {
        initModules(config);
        initServices(config);
    }
}
//执行相应的初始化处理。
void WRAppContext::initialize(const QString& configFileName)
{
    QFile file(configFileName);
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        return;
    }
    QDomDocument document;
    if (!document.setContent(&file, true)) {
        file.close();
        return;
    }
    initialize(document.documentElement());
}

//获取指定类型的服务。
WRAppService* WRAppContext::getService(const QUuid& tuid)
{
    for(WRu i = 0, l = m_serviceHash.count(); i < l; ++i)
    {
        const ServiceEntry& entry = m_serviceHash[i];
        if (entry.uuid() == tuid)
        {
            const WRArray<WRAppService*>& array = entry.data();
            return array[0];
        }
    }
    return 0;
}
//获取指定类型的所有服务。
const WRArray<WRAppService*>& WRAppContext::getAllServices(const QUuid& tuid)
{
    if (tuid.isNull())
    {
        return m_services;
    }
    for(WRu i = 0, l = m_serviceHash.count(); i < l; ++i)
    {
        const ServiceEntry& entry = m_serviceHash[i];
        if (entry.uuid() == tuid)
        {
            return entry.data();
        }
    }
    return WRArray<WRAppService*>::empty();
}
